package lines.gameengine.tracer;

import lines.gameengine.FieldPoint;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;

/**
 * @author vpotapenko
 */
public class FieldPeerLocatorTest {

    private FieldPeerLocator locator;

    @Before
    public void setUp() throws Exception {
        locator = new FieldPeerLocator(9, 9);
    }

    @Test public void shouldShowAllPeerPointsOnInsidePoint() {
        locator.init(new FieldPoint(3, 3));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(2, 3))); // left
        assertThat(locator.next(), equalTo(new FieldPoint(3, 2))); // top
        assertThat(locator.next(), equalTo(new FieldPoint(4, 3))); // right
        assertThat(locator.next(), equalTo(new FieldPoint(3, 4))); // bottom

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowPeerPointsOnLeftInsidePoint() {
        locator.init(new FieldPoint(0, 3));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(0, 2))); // top
        assertThat(locator.next(), equalTo(new FieldPoint(1, 3))); // right
        assertThat(locator.next(), equalTo(new FieldPoint(0, 4))); // bottom

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowPeerPointsOnRightInsidePoint() {
        locator.init(new FieldPoint(8, 3));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(7, 3))); // left
        assertThat(locator.next(), equalTo(new FieldPoint(8, 2))); // top
        assertThat(locator.next(), equalTo(new FieldPoint(8, 4))); // bottom

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowAllPeerPointsOnTopInsidePoint() {
        locator.init(new FieldPoint(3, 0));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(2, 0))); // left
        assertThat(locator.next(), equalTo(new FieldPoint(4, 0))); // right
        assertThat(locator.next(), equalTo(new FieldPoint(3, 1))); // bottom

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowAllPeerPointsOnBottomInsidePoint() {
        locator.init(new FieldPoint(3, 8));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(2, 8))); // left
        assertThat(locator.next(), equalTo(new FieldPoint(3, 7))); // top
        assertThat(locator.next(), equalTo(new FieldPoint(4, 8))); // right

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowAllPeerPointsOnTopLeftPoint() {
        locator.init(new FieldPoint(0, 0));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(1, 0))); // right
        assertThat(locator.next(), equalTo(new FieldPoint(0, 1))); // bottom

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowAllPeerPointsOnTopRightPoint() {
        locator.init(new FieldPoint(8, 0));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(7, 0))); // left
        assertThat(locator.next(), equalTo(new FieldPoint(8, 1))); // bottom

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowAllPeerPointsOnBottomLeftPoint() {
        locator.init(new FieldPoint(0, 8));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(0, 7))); // top
        assertThat(locator.next(), equalTo(new FieldPoint(1, 8))); // right

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowAllPeerPointsOnBottomRightPoint() {
        locator.init(new FieldPoint(8, 8));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(7, 8))); // left
        assertThat(locator.next(), equalTo(new FieldPoint(8, 7))); // top

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }

    @Test public void shouldShowReinitialized() {
        locator.init(new FieldPoint(8, 8));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(7, 8))); // left
        assertThat(locator.next(), equalTo(new FieldPoint(8, 7))); // top

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());

        locator.init(new FieldPoint(0, 8));

        assertThat(locator.hasNext(), equalTo(true));
        assertThat(locator.next(), equalTo(new FieldPoint(0, 7))); // top
        assertThat(locator.next(), equalTo(new FieldPoint(1, 8))); // right

        assertThat(locator.hasNext(), equalTo(false));
        assertThat(locator.next(), nullValue());
    }
}
